package fr.afcepf.atod21.formation.data;

import fr.afcepf.atod21.formation.entity.Stagiaire;
import fr.afcepf.atod21.formation.exception.Atod21Exception;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Types;
import java.util.List;

/**
 * @author Stagiaire
 * @see IDaoStagiaire
 */
public class DaoStagiaireImpl implements IDaoStagiaire {

    /**
     * DataSource utilisée pour l'accès à la BDD
     * 'organisme_formation'.
     */
    private DataSource ds = new Atod21DataSource();

    @Override
    public List<Stagiaire> rechercher(String nom) {
        return null;
    }

    @Override
    public List<Stagiaire> rechercher(int idOrganisme) {
        return null;
    }

    /**
     * Requête permettant l'ajout d'un stagiaire
     * dans la BDD.
     */
    private final String reqAjout =
            "INSERT INTO STAGIAIRE "
                    + "(nom, prenom, adresse, date_naissance, id_organisme) "
                    + "values(?,?,?,?,?)";

    /**
     * Indice du parametre pour le nom du
     * {@link Stagiaire} dans la requête
     * {@link DaoStagiaireImpl#reqAjout}.
     */
    private final int indiceNomReqAjout = 1;

    /**
     * Indice du parametre pour le prénom du
     * {@link Stagiaire} dans la requête
     * {@link DaoStagiaireImpl#reqAjout}.
     */
    private final int indicePrenomReqAjout = 2;

    /**
     * Indice du parametre pour l'adresse du
     * {@link Stagiaire} dans la requête
     * {@link DaoStagiaireImpl#reqAjout}.
     */
    private final int indiceAdresseReqAjout = 3;

    /**
     * Indice du parametre pour le nom du
     * {@link Stagiaire} dans la requête
     * {@link DaoStagiaireImpl#reqAjout}.
     */
    private final int indiceDateNaissanceReqAjout = 4;

    /**
     * Indice du parametre pour l'identifiant
     * de l'{@link fr.afcepf.atod21.formation.entity.Organisme} du
     * {@link Stagiaire} dans la requête
     * {@link DaoStagiaireImpl#reqAjout}.
     */
    private final int indiceIdOrganismeReqAjout = 5;

    @Override
    public Stagiaire ajouter(Stagiaire stagiaire) throws Atod21Exception {
        try {
            Connection cnx = ds.getConnection();
            PreparedStatement pstmt =
                    cnx.prepareStatement(
                            reqAjout,
                            Statement.RETURN_GENERATED_KEYS);
            pstmt.setString(indiceNomReqAjout, stagiaire.getNom());
            pstmt.setString(indicePrenomReqAjout, stagiaire.getPrenom());
            pstmt.setString(indiceAdresseReqAjout, stagiaire.getAdresse());
            pstmt.setDate(indiceDateNaissanceReqAjout, new java.sql.Date(
                    stagiaire.getDateNaissance().getTime()
            ));
            if (stagiaire.getOrganisme() != null) {
                pstmt.setInt(1, stagiaire.getOrganisme().getId());
            } else {
                pstmt.setNull(indiceIdOrganismeReqAjout, Types.INTEGER);
            }

            int resultSql = pstmt.executeUpdate();
            if (resultSql == 1) {
                ResultSet rs = pstmt.getGeneratedKeys();
                if (rs.next()) {
                    stagiaire.setId(rs.getInt(1));
                }
            }

        } catch (SQLException e) {
            throw new Atod21Exception(
                    "erreur 10001: erreur de mySQL à ajout du stagiaire."
            );
        }

        return stagiaire;
    }

    /**
     * Requête permettant le renvoi d'un stagiaire.
     */
    private final String reqRenvoi =
            "UPDATE stagiaire "
                    + "SET id_organisme = null "
                    + "WHERE idstagiaire = ? "
                    + "AND id_organisme = ?";

    /**
     * Indice de l'identifiant du {@link Stagiaire} dans la
     * requête permettant le renvoi de son
     * {@link fr.afcepf.atod21.formation.entity.Organisme}.
     */
    private final int indiceIdStagiaireReqRenvoi = 1;

    /**
     * Indice de l'identifiant du
     * {@link fr.afcepf.atod21.formation.entity.Organisme}
     * dans la requête permettant le renvoi du {@link Stagiaire} de son
     * {@link fr.afcepf.atod21.formation.entity.Organisme}.
     */
    private final int indiceIdOrganismeReqRenvoi = 2;

    @Override

    public Stagiaire renvoi(Stagiaire stagiaire) throws Atod21Exception {

        if (stagiaire.getOrganisme() == null
                || stagiaire.getOrganisme().getId() == 0) {
            throw new Atod21Exception(
                    "erreur 10002: Organisme ou "
                            + "identifiant de l'organisme absent."
            );
        }

        try {
            Connection cnx = ds.getConnection();
            PreparedStatement pstmt =
                    cnx.prepareStatement(reqRenvoi,
                            Statement.KEEP_CURRENT_RESULT);
            pstmt.setInt(indiceIdStagiaireReqRenvoi,
                    stagiaire.getId());
            pstmt.setInt(indiceIdOrganismeReqRenvoi,
                    stagiaire.getOrganisme().getId());

            int resultSql = pstmt.executeUpdate();
            if (resultSql == 1) {
                stagiaire.setOrganisme(null);
            } else {
                throw new Atod21Exception(
                        "erreur 10001: erreur de mySQL au renvoi du stagiaire."
                );
            }

        } catch (SQLException e) {
            throw new Atod21Exception(
                    "erreur 10001: erreur de mySQL au renvoi du stagiaire."
            );
        }

        return stagiaire;
    }
}
